package com.csun.cmny.provider.utils;

import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.temporal.WeekFields;
import java.util.*;

public class DateUtil {
    public static final String year = "yyyy";

    private static Map<String,ThreadLocal<SimpleDateFormat>> sdfMap = new HashMap<String, ThreadLocal<SimpleDateFormat>>();

    private static Logger logger = LoggerFactory.getLogger(DateUtil.class);
    /**
     * 年月日时分秒(无下划线) yyyyMMddHHmmss
     */
    public static final String dtLong = "yyyyMMddHHmmssSSS";

    public static final String dateFormat = "yyyy-MM-dd";

    public static final String yyyyMMdd = "yyyyMMdd";

    public final static String YMDHMS = "yyyyMMddHHmmss";

    /**
     * 时间格式 yyyy-MM-dd HH:mm:ss
     */
    public final static DateFormat YYYY_MM_DD_MM_HH_SS = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * 年月日时分 yyyyMMddHHmm
     */
    public static final String dmLong = "yyyyMMddHHmm";

    public static final String _yearMonth = "yyyy-MM";

    public static String dateToString(Date date){
        return YYYY_MM_DD_MM_HH_SS.format(date);
    }

    /**
     * 获取系统当前日期(精确到月)，格式：yyyy-MM
     *
     * @return
     */
    public static String getDate_yearMonth() {
        Date date = new Date();
        DateFormat df = new SimpleDateFormat(_yearMonth);
        return df.format(date);
    }

    /**
     * 获取系统当前日期(精确到毫秒)，格式：yyyy-MM-dd
     *
     * @return
     */
    public static String getDate_dtShort() {
        Date date = new Date();
        DateFormat df = new SimpleDateFormat(dateFormat);
        return df.format(date);
    }


    public static String getDateString() {
        Date date = new Date();
        DateFormat df = new SimpleDateFormat(yyyyMMdd);
        return df.format(date);
    }


    /**
     * 获取当前日期
     *
     * @return
     */
    public static String getCurrentDate() {
        int y, m, d, h, mi, s;
        Calendar cal = Calendar.getInstance();
        y = cal.get(Calendar.YEAR);
        m = cal.get(Calendar.MONTH) + 1;
        d = cal.get(Calendar.DATE);
        h = cal.get(Calendar.HOUR_OF_DAY);
        mi = cal.get(Calendar.MINUTE);
        s = cal.get(Calendar.SECOND);
        System.out.println("现在时刻是" + y + "-" + m + "-" + d + " " + h + ":" + mi + ":" + s);
        return y + "-" + m + "-" + d + " " + h + ":" + mi + ":" + s;
    }

    public static String getCurrentDate1() {
        int y, m, d, h, mi, s;
        Calendar cal = Calendar.getInstance();
        y = cal.get(Calendar.YEAR);
        m = cal.get(Calendar.MONTH) + 1;
        d = cal.get(Calendar.DATE);
        h = cal.get(Calendar.HOUR_OF_DAY);
        mi = cal.get(Calendar.MINUTE);
        s = cal.get(Calendar.SECOND);
        System.out.println("现在日期是" + y + "-" + m + "-" + d);
        return y + "-" + m + "-" + d;
    }

    /**
     * 根据map中的key得到对应线程的sdf实例
     * @param pattern map中的key
     * @return 该实例
     */
    private static SimpleDateFormat getSdf(final String pattern){
        ThreadLocal<SimpleDateFormat> sdfThread = sdfMap.get(pattern);
        if (sdfThread == null){
            //双重检验,防止sdfMap被多次put进去值
            synchronized (DateUtil.class){
                sdfThread = sdfMap.get(pattern);
                if (sdfThread == null){
                    logger.debug("put new sdf of pattern " + pattern + " to map");
                    sdfThread = new ThreadLocal<SimpleDateFormat>(){
                        @Override
                        protected SimpleDateFormat initialValue() {
                            logger.debug("thread: " + Thread.currentThread() + " init pattern: " + pattern);
                            return new SimpleDateFormat(pattern);
                        }
                    };
                    sdfMap.put(pattern,sdfThread);
                }
            }
        }
        return sdfThread.get();
    }

    /**
     * 按照指定pattern格式化日期
     * @param date 要格式化的date
     * @param pattern 指定格式
     * @return 解析后格式
     */
    public static String formatDate(Date date,String pattern){
        if (date == null){
            throw new IllegalArgumentException("The date must not be null");
        }else {
            return getSdf(pattern).format(date);
        }
    }


    /**
     * 获取系统当前日期(精确到年)，格式：yyyy
     *
     * @return
     */
    public static String getYear() {
        Date date = new Date();
        DateFormat df = new SimpleDateFormat(year);
        return df.format(date);
    }

    /**
     * 将字符串转化成日期格式，格式：yyyy-MM-dd
     *
     * @return
     */
    public static Date getDate(String dateStr) throws ParseException {
        DateFormat df = new SimpleDateFormat(dateFormat);
        return df.parse(dateStr);
    }

    public static Date getDateByString(String dateStr){
        DateFormat df = new SimpleDateFormat(dateFormat);
        try {
            return df.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Date getDateLong(String dateStr){
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            return df.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /*
     *	获取当前周的周一
     * 返回的格式 yyyy-MM-dd
     * */
    public static String getMonday() {
        SimpleDateFormat df2 = new SimpleDateFormat("yyyy-MM-dd"); //设置时间格式
        Calendar c = Calendar.getInstance();
        int day_of_week = c.get(Calendar.DAY_OF_WEEK) - 1;
        if (day_of_week == 0) {
            day_of_week = 7;
        }
        c.add(Calendar.DATE, -day_of_week + 1);
        return df2.format(c.getTime());
    }

    /*
     *	获取当前周的周日
     * 返回的格式 yyyy-MM-dd
     * */
    public static String getSunday() {
        SimpleDateFormat df2 = new SimpleDateFormat("yyyy-MM-dd"); //设置时间格式
        Calendar c = Calendar.getInstance();
        int day_of_week = c.get(Calendar.DAY_OF_WEEK) - 1;
        if (day_of_week == 0) {
            day_of_week = 7;
        }
        c.add(Calendar.DATE, -day_of_week + 7);
        return df2.format(c.getTime());
    }

    /*
     * 获取明天日期
     * */
    public static String getTomorrow(String date) {
        Calendar c = Calendar.getInstance();
        Date date1 = null;
        try {
            date1 = new SimpleDateFormat("yy-MM-dd").parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        c.setTime(date1);
        int day1 = c.get(Calendar.DATE);
        c.set(Calendar.DATE, day1 + 1);
        String time = new SimpleDateFormat("yyyy-MM-dd").format(c.getTime());
        return time;
    }

    /**
     * 获取缴费单号：机构id+时间（精确到毫秒） +随机生成的四位数   1000120180504181234
     * 由于homeid的长度是不固定的，所以在判断缴费单号参数的长度的时候不能用长度进行校验
     *
     * @return
     */
    public static String getPayNumber(Long groupId) {
        String payNumber = "";
        int number = (int) ((Math.random() * 9 + 1) * 1000);//随机生成四位数
        Date date = new Date();
        DateFormat df = new SimpleDateFormat(dtLong);
        String time = df.format(date).substring(0, 14);
        payNumber = groupId.toString() + time + String.valueOf(number);
        return payNumber;
    }

    public static Date convertDateTime(String strDate) {

        //注意：SimpleDateFormat构造函数的样式与strDate的样式必须相符
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");

        //必须捕获异常
        try {
            Date date = simpleDateFormat.parse(strDate);
            return date;
        } catch (ParseException px) {
            px.printStackTrace();
        }
        return null;
    }

    public static int getDaysOfMonth(Date date) {

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
    }

    public static int getDayOfMonth(String yearMonth) {

        String[] years = yearMonth.split("-");

        Calendar c = Calendar.getInstance();
        c.set(Integer.parseInt(years[0]), Integer.parseInt(years[1]), 0); //输入类型为int类型

        return c.get(Calendar.DAY_OF_MONTH);
    }

    public static int getDays(String date) {

        int days = 0;
        boolean isLeapYear = false;
        String year1 = date.split("-")[0];
        int year = Integer.parseInt(year1);
        String month1 = date.split("-")[1];
        int month = Integer.parseInt(month1);
        if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) {
            System.out.println("--------------------闰年-------------------");
            isLeapYear = true;
        } else {
            System.out.println("--------------------非闰年-------------------");
            isLeapYear = false;
        }
        switch (month) {
            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
            case 12:
                days = 31;
                break;
            case 2:
                if (isLeapYear) {
                    days = 29;
                } else {
                    days = 28;
                }
                break;
            case 4:
            case 6:
            case 9:
            case 11:
                days = 30;
                break;
            default:
                break;
        }
        return days;
    }


    /**
     * date2比date1多的天数
     *
     * @param date1
     * @param date2
     * @return
     */
    public static int differentDays(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);

        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);
        int day1 = cal1.get(Calendar.DAY_OF_YEAR);
        int day2 = cal2.get(Calendar.DAY_OF_YEAR);

        int year1 = cal1.get(Calendar.YEAR);
        int year2 = cal2.get(Calendar.YEAR);
        if (year1 != year2)   //同一年
        {
            int timeDistance = 0;
            for (int i = year1; i < year2; i++) {
                if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0)    //闰年
                {
                    timeDistance += 366;
                } else    //不是闰年
                {
                    timeDistance += 365;
                }
            }

            return timeDistance + (day2 - day1);
        } else    //不同年
        {
            return day2 - day1;
        }
    }


    /**
     * 返回系统当前时间(精确到分),作为一个唯一的老人编号,武昌版平移过来的
     *
     * @return 以yyyyMMddHHmm为格式的当前系统时间
     */
    public static String getOldmanNo() {
        Date date = new Date();
        DateFormat df = new SimpleDateFormat(dmLong);
        return df.format(date);
    }

    /*
     *	获取当前日期的前29天的日期
     * 返回的格式 yyyy-MM-dd
     * liqian 2018-09-21
     * */
    public static String getThirty() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date today = new Date();
        Calendar theCa = Calendar.getInstance();
        theCa.setTime(today);
        theCa.add(theCa.DATE, -29);
        Date start = theCa.getTime();
        String day = simpleDateFormat.format(start);
        return day;
    }

    /**
     * 返回系统当天开始时间
     *
     * @return 以yyyy-MM-dd HH:mm:ss为格式
     */
    public static String getStartTimeOfDay(){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY,0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND,0);
        long timeInMillis = calendar.getTimeInMillis();
        return simpleDateFormat.format(timeInMillis);
    }

    /**
     * 返回系统当天结束时间
     *
     * @return 以yyyy-MM-dd HH:mm:ss为格式
     */
    public static String getEndTimeOfDay(){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY,23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND,999);
        long timeInMillis = calendar.getTimeInMillis();
        return simpleDateFormat.format(timeInMillis);
    }

    /**
     * 返回系统当前周周一的开始时间
     *
     * @return 以yyyy-MM-dd HH:mm:ss为格式
     */
    public static String getStartTimeOfWeek(){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar calendar = Calendar.getInstance();
        int day_of_week = calendar.get(Calendar.DAY_OF_WEEK) - 1;
        if (day_of_week == 0) {
            day_of_week = 7;
        }
        calendar.add(Calendar.DATE, -day_of_week + 1);
        calendar.set(Calendar.HOUR_OF_DAY,0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND,0);
        return simpleDateFormat.format(calendar.getTimeInMillis());
    }

    /**
     * 返回系统当前周周日的结束时间
     *
     * @return 以yyyy-MM-dd HH:mm:ss为格式
     */
    public static String getEndTimeOfWeek(){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar calendar = Calendar.getInstance();
        int day_of_week = calendar.get(Calendar.DAY_OF_WEEK) - 1;
        if (day_of_week == 0) {
            day_of_week = 7;
        }
        calendar.add(Calendar.DATE, -day_of_week + 7);
        calendar.set(Calendar.HOUR_OF_DAY,23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND,999);
        return simpleDateFormat.format(calendar.getTimeInMillis());
    }

    @Test
    public void main() throws ParseException {

        Date date = new Date();
//        String str = YYYY_MM_DD_MM_HH_SS.format(date);
//        Date date = YYYY_MM_DD_MM_HH_SS.parse("2019-10-26 08:07:09");

        Calendar cal = Calendar.getInstance();
        cal.setTime(date);

        // 获取周期
        int w = cal.get(Calendar.DAY_OF_WEEK) - 2;
        if (w == -1) {
            w = 6;
        }
        int h = cal.get(Calendar.HOUR_OF_DAY);
        int mi = cal.get(Calendar.MINUTE);

//        String time = str.substring(11, 16);

        System.out.println("w = " + w);
//        System.out.println("time = " + time);

        WeekFields weekFields = WeekFields.of(Locale.getDefault());
        int weekNumber = LocalDate.now().get(weekFields.weekOfWeekBasedYear());

        System.out.println("weekNumber = " + weekNumber);



//        Calendar cal = Calendar.getInstance();
        int day = cal.get(Calendar.DATE);
        int month = cal.get(Calendar.MONTH) + 1;
        int year = cal.get(Calendar.YEAR);
        int dow = cal.get(Calendar.DAY_OF_WEEK);
        int dom = cal.get(Calendar.DAY_OF_MONTH);
        int doy = cal.get(Calendar.DAY_OF_YEAR);

        System.out.println("当期时间: " + cal.getTime());
        System.out.println("日期: " + day);
        System.out.println("月份: " + month);
        System.out.println("年份: " + year);
        System.out.println("一周的第几天: " + dow);  // 星期日为一周的第一天输出为 1，星期一输出为 2，以此类推
        System.out.println("一月中的第几天: " + dom);
        System.out.println("一年的第几天: " + doy);
    }

    /**
     * 获取该月第几天
     *
     * @param recordDate 日期 yyyy-MM-dd
     *
     * @return
     */
    public static int getSec(String recordDate) {

        String end = recordDate.substring(8);
        int day = 0;

        switch (end) {
            case "01" :
                day = 1;
            case "02" :
                day = 2;
            case "03" :
                day = 3;case "04" :
                day = 4;case "05" :
                day = 5;case "06" :
                day = 6;case "07" :
                day = 7;case "08" :
                day = 8;case "09" :
                day = 9;
            default:
                day = Integer.parseInt(end);

        }

        return day;
    }
}
